#ifndef _JOBJECT_H_
#define _JOBJECT_H_
#include "JType.h"
#include "JRtti.h"
//exter	   JObject::InstansMap* m_pInstansMap = 0;

#define JJC_DECLARE_RTTI \
public:\
	static const JRtti m_type;\
	virtual const JRtti& GetType() const\
	{\
		return m_type;\
	}

#define JJC_IMPLEMENT_RTTI(className, pBaseClassType) \
	const JRtti className::m_type = JRtti( L#className, pBaseClassType); 


namespace JJc{
class JObject
{
public:	
	static const JRtti m_type;  
	JObject();
	~JObject();
	bool IsTypeOf(const JObject*) const;
	bool IsTypeOf(const JRtti&) const;

	bool IsDerivedOf(const JObject*) const;
	bool IsDerivedOf(const JRtti&) const;

	virtual const JRtti& GetType()const;

	//ID system
private:
	static uint64    m_instansIdCount;
	uint64           m_instansId;
public:
	uint64 GetID() const;	
	static uint64 GetNextID();
	JObject* GetObjectByID(uint64);
	typedef std::map<uint64,JObject*> InstansMap;
	static InstansMap* m_pInstansMap;

	//Smart Pointer System
private:
	uint64  m_referenceCount;
public:
	uint64 GetReference() const;
	void   IncreaseReference();
	void   DecreaseReference();


};

template<typename T> inline const T* StaticCast(const JObject* pObject)
{
	return static_cast<T*>(pObject);
}

template<typename T> inline       T* StaticCast( JObject* pObject)
{
	return static_cast<T*>(pObject);
}

template<typename T> T* DynamicCast( JObject* pObject)
{
	if(pObject==NULL)	return pObject;
	return  pObject->IsDerivedOf(T::m_type)? (T*)pObject:0;
}

template<typename T> const T* DynamicCast( const JObject* pObject)
{
	if(pObject==NULL)	return pObject;
	return  pObject->IsDerivedOf(T::m_type)? (T*)pObject:0;
}

}

#endif